// HeaderRenderer.cs created with MonoDevelop
// User: dantes at 4:58 PM 10/5/2008
//
// To change standard headers go to Edit->Preferences->Coding->Standard Headers
//

using System;

namespace HollyLibrary.Table
{
	
	
		/// <summary>
	/// Base class for Renderers that draw Column headers
	/// </summary>
	public abstract class HeaderRenderer : Renderer, IHeaderRenderer
	{
		#region Constructor
		
		/// <summary>
		/// Initializes a new instance of the HeaderRenderer class with default settings
		/// </summary>
		protected HeaderRenderer() : base()
		{
			this.StringFormat.Alignment = StringAlignment.Near;
		}

		#endregion


		#region Methods

		/// <summary>
		/// Returns a Gdk.Rectangle that represents the size and location of the Image 
		/// displayed on the ColumnHeader
		/// </summary>
		/// <returns>A Gdk.Rectangle that represents the size and location of the Image 
		/// displayed on the ColumnHeader</returns>
		protected Gdk.Rectangle CalcImageRect()
		{
			Rectangle imageRect = this.ClientRectangle;

			if (imageRect.Width > 16)
			{
				imageRect.Width = 16;
			}

			if (imageRect.Height > 16)
			{
				imageRect.Height = 16;

				imageRect.Y += (this.ClientRectangle.Height - imageRect.Height) / 2;
			}

			return imageRect;
		}


		/// <summary>
		/// Returns a Gdk.Rectangle that represents the size and location of the sort arrow
		/// </summary>
		/// <returns>A Gdk.Rectangle that represents the size and location of the sort arrow</returns>
		protected Gdk.Rectangle CalcSortArrowRect()
		{
			Rectangle arrowRect = this.ClientRectangle;

			arrowRect.Width = 12;
			arrowRect.X = this.ClientRectangle.Right - arrowRect.Width;

			return arrowRect;
		}

		#endregion
		

		#region Properties
		
	

		#endregion


		#region Events

		#region Mouse

		#region MouseEnter

		/// <summary>
		/// Raises the MouseEnter event
		/// </summary>
		/// <param name="e">A HeaderMouseEventArgs that contains the event data</param>
		public virtual void OnMouseEnter(HeaderMouseEventArgs e)
		{
			this.Bounds = e.HeaderRect;

			bool tooltipActive = e.Table.ToolTip.Active;

			if (tooltipActive)
			{
				e.Table.ToolTip.Active = false;
			}

			e.Table.ResetMouseEventArgs();

			e.Table.ToolTip.SetToolTip(e.Table, e.Column.ToolTipText);

			if (tooltipActive)
			{
				e.Table.ToolTip.Active = true;
			}
		}

		#endregion

		#region MouseLeave

		/// <summary>
		/// Raises the MouseLeave event
		/// </summary>
		/// <param name="e">A HeaderMouseEventArgs that contains the event data</param>
		public virtual void OnMouseLeave(HeaderMouseEventArgs e)
		{
			this.Bounds = e.HeaderRect;
		}

		#endregion

		#region MouseUp

		/// <summary>
		/// Raises the MouseUp event
		/// </summary>
		/// <param name="e">A HeaderMouseEventArgs that contains the event data</param>
		public virtual void OnMouseUp(HeaderMouseEventArgs e)
		{
			this.Bounds = e.HeaderRect;
		}

		#endregion

		#region MouseDown

		/// <summary>
		/// Raises the MouseDown event
		/// </summary>
		/// <param name="e">A HeaderMouseEventArgs that contains the event data</param>
		public virtual void OnMouseDown(HeaderMouseEventArgs e)
		{
			if (!e.Table.Focused)
			{
				e.Table.Focus();
			}
			
			this.Bounds = e.HeaderRect;
		}

		#endregion

		#region MouseMove

		/// <summary>
		/// Raises the MouseMove event
		/// </summary>
		/// <param name="e">A HeaderMouseEventArgs that contains the event data</param>
		public virtual void OnMouseMove(HeaderMouseEventArgs e)
		{
			this.Bounds = e.HeaderRect;
		}

		#endregion

		#region Click

		/// <summary>
		/// Raises the Click event
		/// </summary>
		/// <param name="e">A HeaderMouseEventArgs that contains the event data</param>
		public virtual void OnClick(HeaderMouseEventArgs e)
		{
			this.Bounds = e.HeaderRect;
		}


		/// <summary>
		/// Raises the DoubleClick event
		/// </summary>
		/// <param name="e">A HeaderMouseEventArgs that contains the event data</param>
		public virtual void OnDoubleClick(HeaderMouseEventArgs e)
		{
			this.Bounds = e.HeaderRect;
		}

		#endregion

		#endregion
		
		#region Paint

		/// <summary>
		/// Raises the PaintHeader event
		/// </summary>
		/// <param name="e">A PaintHeaderEventArgs that contains the event data</param>
		public virtual void OnPaintHeader(PaintHeaderEventArgs e)
		{
			// paint the Column header's background
			this.OnPaintBackground(e);

			// paint the Column headers foreground
			this.OnPaint(e);
		}


		/// <summary>
		/// Raises the PaintBackground event
		/// </summary>
		/// <param name="e">A PaintHeaderEventArgs that contains the event data</param>
		protected virtual void OnPaintBackground(PaintHeaderEventArgs e)
		{
			
		}


		/// <summary>
		/// Raises the Paint event
		/// </summary>
		/// <param name="e">A PaintHeaderEventArgs that contains the event data</param>
		protected virtual void OnPaint(PaintHeaderEventArgs e)
		{
			
		}
		
		
		/// <summary>
		/// Draws the Image contained in the ColumnHeader
		/// </summary>
		/// <param name="g">The Graphics used to paint the Image</param>
		/// <param name="image">The Image to be drawn</param>
		/// <param name="imageRect">A rectangle that specifies the Size and 
		/// Location of the Image</param>
		/// <param name="enabled">Specifies whether the Image should be drawn 
		/// in an enabled state</param>
		protected void DrawColumnHeaderImage(Gdk.Drawable dr, Gdk.Pixbuf image, Gdk.Rectangle imageRect, bool enabled)
		{
			System.Drawing.Graphics g = Gtk.DotNet.Graphics.FromDrawable( dr );
			System.Drawing.Image img  = GraphUtil.BitmapFromPixbuf( image );
			if (enabled)
			{
				g.DrawImage(image, imageRect);
			}
			else
			{
				using (Image im = new System.Drawing.BitmapBitmap(image, imageRect.Width, imageRect.Height))
				{
					//TODO:
					//ControlPaint.DrawImageDisabled(g, im, imageRect.X, imageRect.Y, this.BackBrush.Color);
				}
			}
		}


		/// <summary>
		/// Draws the ColumnHeader's sort arrow
		/// </summary>
		/// <param name="g">The Graphics to draw on</param>
		/// <param name="drawRect">A Gdk.Rectangle that specifies the location 
		/// of the sort arrow</param>
		/// <param name="direction">The direction of the sort arrow</param>
		/// <param name="enabled">Specifies whether the sort arrow should be 
		/// drawn in an enabled state</param>
		protected virtual void DrawSortArrow(Gdk.Drawable dr, Gdk.Rectangle drawRect, SortOrder direction, bool enabled)
		{
			System.Drawing.Graphics g = Gtk.DotNet.Graphics.FromDrawable( dr );
			if (direction != SortOrder.None)
			{
				using (Font font = new Font("Marlett", 9f))
				{
					using (StringFormat format = new StringFormat())
					{
						
						format.Alignment = StringAlignment.Far;
						format.LineAlignment = StringAlignment.Center;

						if (direction == SortOrder.Ascending)
						{
							if (enabled)
							{
								g.DrawString("t", font, SystemBrushes.ControlDarkDark, drawRect, format);
							}
							else
							{
								using (SolidBrush brush = new SolidBrush(SystemPens.GrayText.Color))
								{
									g.DrawString("t", font, brush, drawRect, format);
								}
							}
						}
						else
						{
							if (enabled)
							{
								g.DrawString("u", font, SystemBrushes.ControlDarkDark, drawRect, format);
							}
							else
							{
								using (SolidBrush brush = new SolidBrush(SystemPens.GrayText.Color))
								{
									g.DrawString("u", font, brush, drawRect, format);
								}
							}
						}
					}
				}
			}
		}

		#endregion

		#endregion
	}
}
